<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
    <title>Leon Sans - Metaball PIXI</title>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            overflow: hidden;
            outline: 0;
            margin: 0;
            padding: 0;
            cursor: move;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script>
</head>

<body>
    <script src="../dist/leon.js"></script>
    <script src="js/util.js"></script>
    <script>
        let container, texture, particleCon;
        let leon, controll, weightControll;
        const particleTotal = 10000;
        let particles = [];
        
        function init() {
            generatePixi(0x000000);

            texture = PIXI.Texture.from('data/drop-alpha.png');
            particleCon = new PIXI.ParticleContainer(particleTotal, {
                vertices: false,
                scale: true,
                position: true,
                rotation: false,
                uvs: false,
                alpha: false
            });
            stage.addChild(particleCon);

            let p, i;
            for (i = 0; i < particleTotal; i++) {
                p = new PIXI.Sprite(texture);
                p.x = sw / 2;
                p.y = sh / 2;
                p.anchor.set(0.5);
                p.scale.x = p.scale.y = 0;
                particleCon.addChild(p);
                particles.push(p);
            }

            const blurFilter = new PIXI.filters.BlurFilter();
            blurFilter.blur = 10;
            blurFilter.autoFit = true;

            const fragSource = [
                    'precision mediump float;',
                    'varying vec2 vTextureCoord;',
                    'uniform sampler2D uSampler;',
                    'uniform float threshold;',
                    'uniform float mr;',
                    'uniform float mg;',
                    'uniform float mb;',
                    'void main(void)',
                    '{',
                    '    vec4 color = texture2D(uSampler, vTextureCoord);',
                    '    vec3 mcolor = vec3(mr, mg, mb);',
                    '    if (color.a > threshold) {',
                    '       gl_FragColor = vec4(mcolor, 1.0);',
                    '    } else {',
                    '       gl_FragColor = vec4(vec3(0.0), 0.0);',
                    '    }',
                    '}'
                ].join('\n');

            const uniformsData = {
                threshold: 0.5,
                mr: 255.0/255.0,
                mg: 255.0/255.0,
                mb: 255.0/255.0,
            };

            const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData);
            stage.filters = [blurFilter, thresholdFilter];
            stage.filterArea = renderer.screen;

            controll = {
                weight: 3,
                color: {},
                outline: true,
                drawing: () => {
                    let i;
                    for (i = 0; i < particleTotal; i++) {
                        TweenMax.killTweensOf(particles[i].scale);
                        TweenMax.set(particles[i].scale, {
                            x: 0,
                            y: 0
                        });
                        TweenMax.to(particles[i].scale, 3, {
                            delay: 0.001 * i,
                            x: particles[i].saveScale,
                            y: particles[i].saveScale,
                            ease: Circ.easeOut
                        });
                    }
                }
            };

            leon = new LeonSans({
                text: 'TOP\n678',
                size: getSize(400),
                weight: 700,
                pathGap: -1,
                isPath: true,
                tracking: 0
            });
            leon.on('update', (model) => {  
                update();
            });
            
            const gui = new dat.GUI();
            gui.add(leon, 'text');
            const sizeControll = gui.add(leon, 'size', 200, 1000);
            gui.add(leon, 'tracking', -6, 10);
            gui.add(leon, 'leading', -8, 10);
            weightControll = gui.add(controll, 'weight', 1, 9);
            gui.add(controll, 'drawing');
            const colorControll = gui.add(controll, 'color', [ 'white', 'black', 'red'] );

            sizeControll.onChange((value) => {
                sizeWeight();
            });

            weightControll.onChange((value) => {
                update();
            });

            colorControll.onChange((value) => {
                if (value == 'white') {
                    renderer.backgroundColor = 0x000000;
                    uniformsData.mr = 255.0/255.0;
                    uniformsData.mg = 255.0/255.0;
                    uniformsData.mb = 255.0/255.0;
                } else if (value == 'black') {
                    renderer.backgroundColor = 0xffffff;
                    uniformsData.mr = 0.0/255.0;
                    uniformsData.mg = 0.0/255.0;
                    uniformsData.mb = 0.0/255.0;
                }  else if (value == 'red') {
                    renderer.backgroundColor = 0xe4c143;
                    uniformsData.mr = 244.0/255.0;
                    uniformsData.mg = 46.0/255.0;
                    uniformsData.mb = 33.0/255.0;
                } 
            });
            colorControll.setValue('white');

            requestAnimationFrame(animate);

            sizeWeight();

            TweenMax.delayedCall(0.1, () => {
                controll.drawing();
            });            
        }

        function sizeWeight() {
            let w;
            if (leon.size > 400) {
                w = (1.5 - 3) / (1000 - 400) * (leon.size - 400) + 3;
            } else {
                w = (3 - 6) / (400 - 200) * (leon.size - 200) + 6;
            }
            weightControll.setValue(w);
        }

        function update() {
            const total = leon.paths.length;
            const sw2 = sw / 2;
            const sh2 = sh / 2;
            let i, p, pos, scale; 
            for (i = 0; i < particleTotal; i++) {
                p = particles[i];
                TweenMax.killTweensOf(p.scale);
                if (i < total) {
                    pos = leon.paths[i];
                    if (pos.type == 'a') {
                        scale = controll.weight * 0.025* leon.scale;
                    } else {
                        scale = controll.weight * 0.01* leon.scale;
                    }
                    p.saveScale = scale;
                    p.x = pos.x;
                    p.y = pos.y;
                    p.scale.x = p.scale.y = scale;
                } else {
                    p.saveScale = 0;
                    p.x = -1000;
                    p.y = -1000;
                    p.scale.x = p.scale.y = 0;                   
                }
            }        
        }

        function animate(t) {
            requestAnimationFrame(animate);

            const x = (sw - leon.rect.w) / 2;
            const y = (sh - leon.rect.h) / 2;
            leon.position(x + moveX, y + moveY);

            renderer.render(stage);
        }

        window.onload = () => {
            init();
        };
    </script>
</body>

</html>